package com.laomuji.android.mvvm.utils

import android.Manifest
import android.content.ContentResolver
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.MediaStore
import android.util.Base64
import com.laomuji.android.mvvm.utils.permission.PermissionCallback
import com.laomuji.android.mvvm.utils.permission.PermissionUtil
import java.io.BufferedOutputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream

/**
 * 图片工具
 * @author laomuji666
 * @since 2024/2/21
 */
object ImageUtil {

    /**
     * uri转bitmap
     * @param uri uri
     * @param contentResolver contentResolver
     * @return 读取后的图片
     */
    fun uriToBitmap(uri: Uri?, contentResolver: ContentResolver): Bitmap? {
        try {
            return BitmapFactory.decodeStream(contentResolver.openInputStream(uri!!))
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 压缩图片,每次减少一半大小,直到不大于指定大小为止
     * @param bitmapVal 图片
     * @param maxByte 最大字节
     * @return 压缩后的图片
     */
    fun compressBitmap(bitmapVal: Bitmap, maxByte: Int): Bitmap {
        var bitmap = bitmapVal
        val stream = ByteArrayOutputStream()
        var bytes: ByteArray
        val matrix = Matrix()
        matrix.setScale(0.5f, 0.5f)
        do {
            stream.reset()
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
            bytes = stream.toByteArray()
        } while (bytes.size > maxByte)
        return bitmap
    }

    /**
     * 旋转图片
     * @param bitmapVal 图片
     * @param degrees 角度
     * @return 旋转后的图片
     */
    fun rotateBitmap(bitmapVal: Bitmap, degrees: Float): Bitmap {
        var bitmap = bitmapVal
        val m = Matrix()
        m.setRotate(degrees, bitmap.width.toFloat() / 2, bitmap.height.toFloat() / 2)
        return try {
            val b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, m, true)
            if (bitmap != b2) {
                bitmap.recycle()
                bitmap = b2
            }
            bitmap
        } catch (ex: Exception) {
            bitmap
        }
    }

    /**
     * bitmap转换为文件
     * @param bitmap 图片
     * @param filename 文件名,使用缓存路径+文件名
     * @return 转换后的文件
     */
    fun bitMapToFile(bitmap: Bitmap, filename: String, context: Context): File {
        val file = File(context.cacheDir, filename)
        try {
            val bos = BufferedOutputStream(FileOutputStream(file))
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos)
            bos.flush()
            bos.close()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return file
    }

    /**
     * base64转图片
     * @param base64Data base64字符串
     * @return 转换后的图片
     */
    fun base64ToBitmap(base64Data: String): Bitmap {
        val bytes = Base64.decode(base64Data, Base64.DEFAULT)
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
    }

    /**
     * bitmap转base64
     */
    fun bitmapToBase64(bitmap: Bitmap?): String {
        try {
            if (bitmap != null) {
                val stream = ByteArrayOutputStream()
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
                stream.flush()
                stream.close()
                return Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT)
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return ""
    }

    /**
     * drawable转bitmap
     * @param drawable drawable
     * @return 转换后的图片
     */
    fun drawableToBitmap(drawable: Drawable): Bitmap {
        val width = drawable.intrinsicWidth
        val height = drawable.intrinsicHeight
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, width, height)
        drawable.draw(canvas)
        return bitmap
    }


    /**
     * 保存到相册回调
     */
    interface SaveBitmapToAlbumCallback {
        fun onSuccess()
        fun onFail()
    }

    /**
     * 保存bitmap到相册
     */
    fun saveBitmapToAlbum(bitmap: Bitmap?, callback: SaveBitmapToAlbumCallback, contentResolver: ContentResolver) {
        try {
            val filename = System.currentTimeMillis().toString() + ".png"
            val saveResult = MediaStore.Images.Media.insertImage(
                contentResolver,
                bitmap,
                filename,
                null
            )
            if (saveResult == null) {
                PermissionUtil.requestPermissions(object : PermissionCallback() {
                    override fun onGranted() {
                        MediaStore.Images.Media.insertImage(
                            contentResolver,
                            bitmap,
                            filename,
                            null
                        )
                        callback.onSuccess()
                    }
                }, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            } else {
                callback.onSuccess()
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            callback.onFail()
        }
    }

}